/**************************************************************************
 * @name   user.c
 * @brief  用户链表
 * @date   2025/01/06
 * @anchor boluzs@163.com
 * @note
 *
 * @version 1.0.0
 *
 * 版权声明
 * CopyRight (c)   2019-2024   boluzs@163.com    All Right Reciver
 **************************************************************************/
#include "user.h"
#include "start.h"
#include "main.h"

// 用户添加信息
void User_Add(User_p User)
{
    char user_info[256];

    // 格式化用户信息
    snprintf(user_info, sizeof(user_info), "|%s|%s|%s|%s|\n", User->Account, User->Passwd, "0.00", cur_datetime);

    // 写入文件
    FILE *fp = fopen(USER_FILE_PATH, "a+b");
    if (fp != NULL)
    {
        fputs(user_info, fp);
        fclose(fp);
        printf("用户信息已添加。\n");
    }
    else
    {
        fprintf(stderr, "无法打开文件进行写入。 Error,errno=%d,%s\n", errno, strerror(errno));
    }
}

/**************************************************************************
 * @name: User_Check
 * @brief: 登录的时候从用户文件中校验这个用户的账号和密码是否一致
 * @param {User_p} user
 * @note: None
 * @retval: ture or false
 **************************************************************************/
bool User_Check(User_p user)
{
    char *line = (char *)calloc(1, 128);
    bool found = false;

    FILE *fp = fopen(USER_FILE_PATH, "rb");
    if (fp != NULL)
    {
        while (fgets(line, 128, fp))
        {
            // 格式化读取文件中的数据
            User_p file_user = (User_p)calloc(1, sizeof(User_t));

            sscanf(line, "|%11[^|]|%6[^|]|%lf|%31[^\n]|", file_user->Account, file_user->Passwd, &file_user->Balance, file_user->CreateTime);

            // 比较账号和密码
            if (strcmp(file_user->Account, user->Account) == 0 && strcmp(file_user->Passwd, user->Passwd) == 0)
            {
                printf("用户信息匹配: %s", line);
                User_Credit_Get(file_user->Account, &file_user->Balance);
                login_user = file_user;
                found = true;
                break; // 找到匹配项后退出，不需要释放用户内存
            }
            free(file_user); // 不匹配则需要释放掉内存
        }
        fclose(fp);

        if (!found)
        {
            printf("无匹配用户或密码错误\n");
        }
    }
    else
    {
        fprintf(stderr, "无法打开文件进行读取。Error, errno=%d, %s\n", errno, strerror(errno));
    }
    free(line);
    return found;
}

/**************************************************************************
 * @name: User_Credit_Add
 * @brief: 用户充值接口
 * @note:
 *          1.打开或创建一个通过用户账号的文本（比如12345678901.txt），ab：二进制模式追加打开，没有则创建
 *          2.将数据写入到文本中
 * @retval: None
 **************************************************************************/
void User_Credit_Add(double money)
{

    char *user_file_name = (char *)calloc(1, 64);
    char *user_info = (char *)calloc(1, 256);

    // 格式化用户信息
    snprintf(user_file_name, 64, "/tmp/starge_project/Data/userMoney/%s%s", login_user->Account, ".txt");
    login_user->Balance += money;
    snprintf(user_info, 256, "|%s|%.2f|%s|%.2f|\n", login_user->Account, money, cur_datetime, login_user->Balance);
    // 打开文件
    FILE *fp = fopen(user_file_name, "ab");
    // 写入文件
    if (fp != NULL)
    {
        fputs(user_info, fp);
        fclose(fp);
        printf("充值%.2f元成功,充值后用户余额%.2f！\n", money, login_user->Balance);
    }
    else
    {
        fprintf(stderr, "无法打开文件进行写入。 Error,errno=%d,%s\n", errno, strerror(errno));
    }
    free(user_info);
    free(user_file_name);
}

/**************************************************************************
 * @name: User_Credit_Sub
 * @brief: 用户消费接口
 * @note:
 *          1.打开或创建一个通过用户账号的文本（比如12345678901.txt），ab：二进制模式追加打开，没有则创建
 *          2.需要判断用户余额是否足够消费
 *          2.将数据写入到文本中
 * @retval: 成功返回true，失败返回false
 **************************************************************************/
bool User_Credit_Sub(double money)
{

    char *user_file_name = (char *)calloc(1, 64);
    char *user_info = (char *)calloc(1, 256);

    // 格式化用户信息
    snprintf(user_file_name, 64, "/tmp/starge_project/Data/userMoney/%s%s", login_user->Account, ".txt");

    if (login_user->Balance - money < 0)
    {
        free(user_info);
        free(user_file_name);
        return false;
    }
    else
    {
        login_user->Balance -= money;
        snprintf(user_info, 256, "|%s|-%.2f|%s|%.2f|\n", login_user->Account, money, cur_datetime, login_user->Balance);
        // 打开文件
        FILE *fp = fopen(user_file_name, "ab");
        // 写入文件
        if (fp != NULL)
        {
            fputs(user_info, fp);
            fclose(fp);
            printf("充值%.2f元成功,充值后用户余额%.2f！\n", money, login_user->Balance);
        }
        else
        {
            fprintf(stderr, "无法打开文件进行写入。 Error,errno=%d,%s\n", errno, strerror(errno));
        }
        free(user_info);
        free(user_file_name);
        return true;
    }
}

/**************************************************************************
 * @name: User_Credit_Get
 * @brief: 获取用户账户余额
 * @note: None
 * @retval: None
 **************************************************************************/
bool User_Credit_Get(char *account, double *balance)
{
    char *user_file_name = (char *)calloc(1, 64);
    char *line = (char *)calloc(1, 128);
    bool found = false;
    // 格式化用户信息
    snprintf(user_file_name, 64, "/tmp/starge_project/Data/userMoney/%s%s", account, ".txt");
    FILE *fp = fopen(user_file_name, "rb");
    if (fp != NULL)
    {
        UserC_p file_user = (UserC_p)calloc(1, sizeof(UserC_t));
        while (fgets(line, 128, fp))
        {
            // 格式化读取文件中的数据
            sscanf(line, "|%11[^|]|%lf|%31[^|]|%lf|", file_user->Account, &file_user->Money, file_user->CreateTime, &file_user->Balance);
            *balance = file_user->Balance;
            found = true;
        }
        free(file_user);
        fclose(fp);
    }
    else
    {
        fprintf(stderr, "无法打开文件进行读取。Error, errno=%d, %s\n", errno, strerror(errno));
    }
    free(line);
    free(user_file_name);
    return found;
}

void User_Credit_List(void)
{
    char *user_file_name = (char *)calloc(1, 64);
    char *line = (char *)calloc(1, 128);
    // 格式化用户信息
    snprintf(user_file_name, 64, "/tmp/starge_project/Data/userMoney/%s%s", login_user->Account, ".txt");
    FILE *fp = fopen(user_file_name, "rb");
    if (fp != NULL)
    {
        Show_Font(22, 100, 22, 4, getColor(0, 128, 89, 60), 20, 0, "用户账号", getColor(0, 41, 250, 26), 100, 50, 40);
        Show_Font(22, 100, 22, 4, getColor(0, 128, 89, 60), 20, 0, "流水金额", getColor(0, 41, 250, 26), 100, 175, 40);
        Show_Font(22, 200, 22, 4, getColor(0, 128, 89, 60), 70, 0, "流水时间", getColor(0, 41, 250, 26), 200, 300, 40);
        Show_Font(22, 100, 22, 4, getColor(0, 128, 89, 60), 20, 0, "账号余额", getColor(0, 41, 250, 26), 100, 525, 40);
        UserC_p file_user = (UserC_p)calloc(1, sizeof(UserC_t));
        int i = 0;
        while (fgets(line, 128, fp))
        {
            // 格式化读取文件中的数据
            sscanf(line, "|%11[^|]|%lf|%31[^|]|%lf|", file_user->Account, &file_user->Money, file_user->CreateTime, &file_user->Balance);
            char *user_money = (char *)calloc(1, 16);
            char *user_balance = (char *)calloc(1, 16);
            sprintf(user_money, "%.2f", file_user->Money);
            sprintf(user_balance, "%.2f", file_user->Balance);
            // 将数据以列表的形式输出到开发板
            Show_Font(22, 100, 22, 4, getColor(0, 128, 89, 60), 0, 0, file_user->Account, getColor(0, 255, 255, 255), 100, 50, 60 + i);
            Show_Font(22, 100, 22, 4, getColor(0, 128, 89, 60), 30, 0, user_money, getColor(0, 255, 255, 255), 100, 175, 60 + i);
            Show_Font(22, 200, 22, 4, getColor(0, 128, 89, 60), 30, 0, file_user->CreateTime, getColor(0, 255, 255, 255), 200, 300, 60 + i);
            Show_Font(22, 100, 22, 4, getColor(0, 128, 89, 60), 30, 0, user_balance, getColor(0, 255, 255, 255), 100, 525, 60 + i);
            free(user_money);
            free(user_balance);
            i += 20;
        }
        free(file_user);
        fclose(fp);
    }
    else
    {
        fprintf(stderr, "无法打开文件进行读取。Error, errno=%d, %s\n", errno, strerror(errno));
    }
    free(line);
    free(user_file_name);
}